import {Alert} from 'react-native';
import AsyncStorage from '@react-native-async-storage/async-storage';
import shuffle from 'lodash.shuffle';

import {flow, makeObservable, observable} from 'mobx';
import {
  personal_fm,
  song_detail,
  lyric as lyricApi,
  auto_song_url,
  fm_trash,
} from '../apis';

import TrackPlayer, {State, RepeatMode} from 'react-native-track-player';

TrackPlayer.setupPlayer({});
TrackPlayer.registerPlaybackService(() => require('./service'));

let fm_queue = []; // FM等待队列

const confirm = (title, msg, ok, cancel) => {
  return new Promise(resolve => {
    Alert.alert(title, msg, [
      {
        text: cancel,
        onPress: () => {
          resolve(false);
        },
        style: 'cancel',
      },
      {text: ok, onPress: () => resolve(true)},
    ]);
  });
};

TrackPlayer.setRepeatMode(RepeatMode.Off);

const CAHCE_KEY_PRE = 'music@version:v1@id:';

class PlayerStore {
  random_ids = [];
  list_ids = [];
  current_index = 0;
  current_playlist_id = null;

  @observable fm_poster;
  @observable mode = '';
  @observable loop_mode = 'list';
  @observable current = {
    // 当前歌曲信息
    id: undefined,
    uri: '', // 链接
    name: '', // 标题
    artists: '', // 艺术家
    poster: '', // 封面
    genre: '', // 专辑
  };
  @observable lyric = ''; // 当前播放歌词
  @observable total_duration = 180000; // 音乐长度

  constructor() {
    makeObservable(this);
  }

  @flow.bound
  *setLoop(mode) {
    this.loop_mode = mode;
    if (mode === 'signal') {
      yield TrackPlayer.setRepeatMode(RepeatMode.Track);
    } else {
      yield TrackPlayer.setRepeatMode(RepeatMode.Off);
    }

    if (this.loop_mode === 'random') {
      this.current_index = this.random_ids.findIndex(
        i => i === this.current?.id,
      );
    } else {
      this.current_index = this.list_ids.findIndex(i => i === this.current?.id);
    }
  }

  @flow.bound
  *loadLrc(id) {
    this.lyric = '[00:00.000] 歌词加载中...';
    this.lyric = yield lyricApi(id);
  }

  @flow.bound
  *loadFm() {
    // 如果等待队列小于2则获取数据，加入队列
    if (fm_queue.length <= 1) {
      const {data} = yield personal_fm();
      if (Array.isArray(data)) {
        for (const music of data) {
          if (!this.fm_poster) this.fm_poster = music.album.picUrl;
          fm_queue.push(music);
        }
      }
    }
  }

  clearFm() {
    fm_queue = [];
  }

  @flow.bound
  *fmTrash(id) {
    yield fm_trash(id);
    yield this.pushFm();
  }

  @flow.bound
  *startPlayFm() {
    // 如果已经在播放FM，跳过
    if (this.mode === 'fm') {
      const state = yield TrackPlayer.getState();
      // 如果暂停，继续播放
      if (state === State.Paused) {
        TrackPlayer.play();
      }
      return;
    }

    yield TrackPlayer.setRepeatMode(RepeatMode.Off);
    this.mode = 'fm';

    if (fm_queue.length === 0) {
      // 加载到等待队列
      yield this.loadFm();
    }

    // 添加到播放列表
    yield this.pushFm();
  }

  @flow.bound
  *pushFm() {
    const music = fm_queue.shift();
    if (music) {
      // 重置播放列表
      const url = auto_song_url(music.id);
      this.fm_poster = music.album.picUrl;
      yield this.play({
        id: music.id,
        uri: url,
        name: music.name,
        artists: music.artists.map(i => i.name).join('/'), // 艺术家
        poster: music.album.picUrl, // 封面
        genre: music.album.name, // 专辑
      });
      // 加载FM到等待队列
      this.loadFm();
    } else {
      console.log('FM没有等待队列为空...');
    }
  }

  @flow.bound
  *startPlayList(id, music_id, ids) {
    this.mode = 'list';
    if (this.current_playlist_id !== id) {
      if (this.loop_mode === 'signal') {
        TrackPlayer.setRepeatMode(RepeatMode.Track);
      } else {
        TrackPlayer.setRepeatMode(RepeatMode.Off);
      }

      const ok = yield confirm(
        '提示',
        '替换当前播放列表，是否继续？如歌单过长可能需要比较久时间',
        '继续',
        '不了',
      );
      if (ok) {
        this.list_ids = ids;
        this.random_ids = shuffle(ids);
        this.current_playlist_id = id;
      } else {
        return false;
      }
    }

    if (this.current?.id !== music_id) {
      yield this.playListByMusicId(music_id);
    }
  }

  @flow.bound
  *loadMusicFromNetwork(ids) {
    const {songs} = yield song_detail(ids);
    const list = [];
    if (songs.length > 0) {
      for (const music of songs) {
        const uri = auto_song_url(music.id);
        list.push({
          id: music.id, // id
          uri, // url
          name: music.name, // 标题
          artists: music.ar.map(i => i.name).join('/'), // 艺术家
          poster: music.al.picUrl, // 封面
          genre: music.al.name, // 专辑
        });
      }
    }
    return list;
  }

  @flow.bound
  *loadMusicFromCache(id) {
    try {
      const cache = yield AsyncStorage.getItem(`${CAHCE_KEY_PRE}${id}`);
      if (cache !== null) {
        console.log('从缓存获取到歌曲...成功', cache);
        return JSON.parse(cache);
      }
    } catch (e) {
      console.log('从缓存获取到歌曲...失败', e);
    }

    let result = false;
    const list = yield this.loadMusicFromNetwork([id]);
    if (list.length > 0) {
      yield AsyncStorage.setItem(
        `${CAHCE_KEY_PRE}${list[0].id}`,
        JSON.stringify(list[0]),
      );
      console.log('从网络获取到歌曲...成功', list[0]);
      result = list[0];
    }
    const ids = this.loop_mode === 'random' ? this.random_ids : this.list_ids;
    const target_index = ids.findIndex(i => i === id);
    const next_10ids = ids.slice(target_index + 1, target_index + 50);
    this.loadMoreMusic2Cache(next_10ids);
    return result;
  }

  @flow.bound
  *loadMoreMusic2Cache(ids) {
    const network_ids = [];
    for (const iid of ids) {
      try {
        const cache = yield AsyncStorage.getItem(`${CAHCE_KEY_PRE}${iid}`);
        if (cache === null) {
          network_ids.push(iid);
        }
      } catch (error) {
        network_ids.push(iid);
      }
    }
    if (network_ids.length > 0) {
      console.log('获取更多的歌曲从网络资源...', network_ids);
      const list = yield this.loadMusicFromNetwork(network_ids);
      if (list.length > 0) {
        for (const item of list) {
          yield AsyncStorage.setItem(
            `${CAHCE_KEY_PRE}${item.id}`,
            JSON.stringify(item),
          );
        }
        console.log('从网络获取到歌曲...成功', list.length);
      }
    }
  }

  @flow.bound
  *playListByMusicId(id) {
    const music = yield this.loadMusicFromCache(id);
    console.log('开始播放音乐...', music);
    if (!music) {
      global.showToast({
        title: '歌曲已失效',
        icon: 'none',
      });
      this.skipToNext();
      return;
    } else {
      yield this.play(music);
    }
  }

  @flow.bound
  *play(music) {
    this.current = music;
    if (this.loop_mode === 'random') {
      this.current_index = this.random_ids.findIndex(i => i === music.id);
    } else {
      this.current_index = this.list_ids.findIndex(i => i === music.id);
    }
    yield TrackPlayer.reset();
    yield TrackPlayer.add({
      id: music.id, // id
      url: music.uri, // url
      title: music.name, // 标题
      artist: music.artists, // 艺术家
      artwork: music.poster, // 封面
      genre: music.genre, // 专辑
    });
    yield this.loadLrc(music.id);
    yield TrackPlayer.play();
  }

  @flow.bound
  *skipToNext(user_handle = true) {
    if (this.mode === 'fm') {
      yield this.pushFm();
    }

    if (this.mode === 'list') {
      if (!user_handle && this.loop_mode === 'signal') return; // 自动播放下一首，单曲循环不切歌
      this.current_index++;
      if (this.current_index < 0)
        this.current_index === this.random_ids.length - 1;
      if (this.current_index >= 0) this.current_index === 0;
      if (this.loop_mode === 'random') {
        yield this.playListByMusicId(this.random_ids[this.current_index]);
      } else {
        yield this.playListByMusicId(this.list_ids[this.current_index]);
      }
    }
  }

  @flow.bound
  *skipToPrevious() {
    if (this.mode === 'list') {
      this.current_index--;
      if (this.current_index < 0)
        this.current_index === this.random_ids.length - 1;
      if (this.current_index >= 0) this.current_index === 0;
      if (this.loop_mode === 'random') {
        yield this.playListByMusicId(this.random_ids[this.current_index]);
      } else {
        yield this.playListByMusicId(this.list_ids[this.current_index]);
      }
    }
  }
}

const store = new PlayerStore();

export default store;
